package SGUI

import (
	. "SGEngine2"
	"dom4g"
	"strconv"
	"strings"
)

const (
	Widget_Auto = iota
	Widget_Px
	Widget_Percent
)

type WidgetInfo struct {
	Component2D
	ID         string
	Top        *TopWidget
	Parent     IWidget
	Margin     QuadRect
	attribute  map[string]interface{}
	WidthType  int
	HeightType int
}

type IWidget interface {
	GetWidgetInfo() *WidgetInfo
	OnLoad()
	OnReSize()
	GetSize() (float32, float32)
	GetLayoutSize() (float32, float32)
}

func (this *WidgetInfo) GetAttr(key string) interface{} {
	v, ok := this.attribute[key]
	if ok {
		return v
	}
	return ""
}

func (this *WidgetInfo) OnReSize() {

}

func (this *WidgetInfo) AddAttr(k, v string) {
	if this.attribute == nil {
		this.attribute = make(map[string]interface{})
	}

	if len(v) > 0 && v[0] == '[' {
		NewV := v[1 : len(v)-1]
		this.attribute[k] = strings.Split(NewV, " ")
	} else if len(v) > 0 && v[0] == '$' {
		if this.Top != nil {
			this.attribute[k] = this.Top.UserData.(map[string]interface{})[v[1:len(v)-1]]
		}
	} else {

		this.attribute[k] = v
	}
}

func (this *WidgetInfo) GetLayoutSize() (float32, float32) {

	return this.Width + this.Margin.Left + this.Margin.Right, this.Height + this.Margin.Top + this.Margin.Bottom
}

func (w *WidgetInfo) SetSize(width, height float32) {
}

func (t *WidgetInfo) OnAttach(node *Node) {

}
func (w *WidgetInfo) GetSize() (float32, float32) {
	var px, py float32
	var wd, he float32
	if w.Parent != nil {
		px, py = w.Parent.GetSize()
	} else {
		px, py = float32(RootView.Width), float32(RootView.Height)
	}
	if w.WidthType == Widget_Px {
		wd = w.Width
	} else if w.WidthType == Widget_Auto {
		wd = px
	}

	if w.HeightType == Widget_Px {
		he = w.Height
	} else if w.HeightType == Widget_Auto {
		he = py
	}
	return wd, he
}
func (w *WidgetInfo) OnLoad() {

}

func (w *WidgetInfo) OnDetach(node *Node) {

}

func (w *WidgetInfo) OnUpdate() {

}
func parseNodeAttrs(elem *dom4g.Element, widget IWidget, p IWidget) {
	node := widget.GetWidgetInfo().Node
	if v, ok := elem.AttrValue("Scale"); ok {
		ScaleStrArr := strings.Split(v, ",")
		x, _ := strconv.ParseFloat(ScaleStrArr[0], 32)
		y, _ := strconv.ParseFloat(ScaleStrArr[1], 32)
		z, _ := strconv.ParseFloat(ScaleStrArr[2], 32)
		node.Scale = Vec3{x, y, z}
	}

	if v, ok := elem.AttrValue("Position"); ok {
		PosStrArr := strings.Split(v, ",")
		x, _ := strconv.ParseFloat(PosStrArr[0], 32)
		y, _ := strconv.ParseFloat(PosStrArr[1], 32)
		z, _ := strconv.ParseFloat(PosStrArr[2], 32)
		node.Position = Vec3{x, y, z}
	}

	if v, ok := elem.AttrValue("Active"); ok {
		if v == "false" {
			node.SetActive(false)
		} else if v == "true" {
			node.SetActive(true)
		}
	}

	parseNodeEvent(elem, widget)
	parseRenderPivot(elem, widget)
	parseNodeLayout(elem, widget, p)
}

func parseRenderPivot(elem *dom4g.Element, widget IWidget) {
	rc := &widget.GetWidgetInfo().Component2D

	if v, ok := elem.AttrValue("Pivot"); ok {
		switch v {
		case "Left":
			rc.Pivot = Pivot_LEFT
		case "Top":
			rc.Pivot = Pivot_TOP
		case "TopLeft":
			rc.Pivot = Pivot_TOPLEFT
		case "TopRight":
			rc.Pivot = Pivot_TOPRIGHT
		case "Center":
			rc.Pivot = Pivot_CENTER
		case "Bottom":
			rc.Pivot = Pivot_BOTTOM
		case "BottomLeft":
			rc.Pivot = Pivot_BOTTOMLEFT
		case "BottomRight":
			rc.Pivot = Pivot_BOTTOM_RIGHT
		}
	}
}

func parseNodeEvent(elem *dom4g.Element, widget IWidget) {
	node := widget.GetWidgetInfo().Node
	tw := widget.GetWidgetInfo().Top
	var em *EventMessage
	mdv, mdok := elem.AttrValue("OnMouseDown")
	muv, muok := elem.AttrValue("OnMouseUp")
	if mdok || muok {
		em = &EventMessage{}
		//MouseDown
		if mdok {
			ParamArr := strings.Split(mdv, ":")
			em.RegisterEvent(EVENT_MOUSEDOWN, func(em *EventMessage, x int, y int) {
				tw.CallEvent(ParamArr[1], node, ParamArr[0])
			})
		}
		//MouseUp
		if muok {
			ParamArr := strings.Split(muv, ":")
			em.RegisterEvent(EVENT_MOUSEUP, func(em *EventMessage, x int, y int) {
				tw.CallEvent(ParamArr[1], node, ParamArr[0])
			})
		}
		node.Add(em)
	}

}
func IfGetIWidget(k string, v interface{}) bool {
	_, ok := v.(IWidget)
	return ok
}

func parseNodeLayout(elem *dom4g.Element, widget IWidget, p IWidget) {

	if v, ok := elem.AttrValue("margin"); ok {
		MarginArr := strings.Split(v, " ")
		left, _ := strconv.ParseFloat(MarginArr[0], 32)
		top, _ := strconv.ParseFloat(MarginArr[1], 32)
		bottom, _ := strconv.ParseFloat(MarginArr[2], 32)
		right, _ := strconv.ParseFloat(MarginArr[2], 32)

		widget.GetWidgetInfo().Margin.Left = float32(left)
		widget.GetWidgetInfo().Margin.Top = float32(top)
		widget.GetWidgetInfo().Margin.Bottom = float32(bottom)
		widget.GetWidgetInfo().Margin.Right = float32(right)
	}
	strw, ok0 := elem.AttrValue("Width")
	if ok0 {
		w, _ := strconv.ParseFloat(strw, 32)
		widget.GetWidgetInfo().Width = float32(w)
		widget.GetWidgetInfo().WidthType = Widget_Px
	} else {
		if p != nil {
			widget.GetWidgetInfo().Width = p.GetWidgetInfo().Width
			widget.GetWidgetInfo().WidthType = Widget_Auto
		}
	}
	strh, ok1 := elem.AttrValue("Height")
	if ok1 {
		h, _ := strconv.ParseFloat(strh, 32)
		widget.GetWidgetInfo().Height = float32(h)
		widget.GetWidgetInfo().HeightType = Widget_Px
	} else {
		if p != nil {
			widget.GetWidgetInfo().Height = p.GetWidgetInfo().Height
			widget.GetWidgetInfo().HeightType = Widget_Auto
		}
	}

}
